#include "base.h"
#include "service_center.h"
#include "task_service.h"
#include "timer_service.h"

cheetah_service_center SC;

#define handle2index(handle) (handle%TQ_LIST_HASH_SIZE)

cheetah_service_cache_node_list* cheetah_service_cache_node_create() {
	typedef cheetah_service_cache_node_list list_type;
	list_type* list = (list_type*)malloc(sizeof(list_type));
	assert(list);
	return list;
}

void cheetah_service_center_tick(void* ctx, void* param);

int32 cheetah_service_center_init() {
	cheetah_service_center* sc = &SC;
	sc->service_cache_node_list_.head_ = sc->service_cache_node_list_.tail_ = 0;
	sc->service_cache_node_list_.lock_ = 0;
	memset(sc->service_hnode_list_, 0, sizeof(sc->service_hnode_list_));;
	sc->delay_free_list_ = 0;
	sc->timer_ = cheetah_timer_create(10, cheetah_service_center_tick, 0, 0);;
	return 1;
}

int32 cheetah_service_center_add_service(cheetah_service* s) {
	cheetah_service_center* sc = &SC;
	cheetah_service_cache_node_list* cache_list = &sc->service_cache_node_list_;
	ATOM_LOCK(&sc->service_cache_node_list_.lock_);
	if (cache_list->tail_) {
		assert(cache_list->head_);
		cache_list->tail_->next_ = s;
		cache_list->tail_ = s;
	}
	else {
		cache_list->head_ = cache_list->tail_ = s;
	}
	ATOM_UNLOCK(&sc->service_cache_node_list_.lock_);
	return 1;
}

int32 cheetah_service_center_add_service_immediately(cheetah_service* s) {
	cheetah_service_center* sc = &SC;
	uint32 index;
	assert(s);
	index = handle2index(s->handle_);

	cheetah_service* hnode = sc->service_hnode_list_[index];
	if (hnode) {
		if (hnode->handle_ == s->handle_) {
			return 0;
		}
		else {
			cheetah_service* parent = hnode;
			hnode = hnode->next_;
			while (hnode)
			{
				if (hnode->handle_ == s->handle_) {
					assert(0);
					return 0;
				}
				parent = hnode;
				hnode = hnode->next_;
			}
		}
	}
	s->next_ = sc->service_hnode_list_[index];
	sc->service_hnode_list_[index] = s;
	cheetah_task_service_add_tq(s->tq_);
	cheetah_timer_service_add_timer(s->timer_);

	return 1;
}

void cheetah_service_center_cache_service_tick() {
	cheetah_service_center* sc = &SC;
	cheetah_service* s;

	ATOM_LOCK(&sc->service_cache_node_list_.lock_);
	s = sc->service_cache_node_list_.head_;
	sc->service_cache_node_list_.head_ = 0;
	sc->service_cache_node_list_.tail_ = 0;
	ATOM_UNLOCK(&sc->service_cache_node_list_.lock_);

	while (s) {
		cheetah_service* addnode = s;
		s = s->next_;
		addnode->next_ = 0;
		cheetah_service_center_add_service_immediately(addnode);
	}
}

int32 cheetah_service_center_remove_service(cheetah_handle handle) {
	
	return 1;
}

void cheetah_service_center_tick(void* ctx, void* param) {
	cheetah_service_center_cache_service_tick();

}

void cheetah_task_center_start() {
	cheetah_service_center* sc = &SC;
	cheetah_timer_service_add_timer(sc->timer_);
}
